package cn.hzc.fortess.system.service;

import cn.hzc.fortess.core.common.BizErrorEnum;
import cn.hzc.fortess.core.common.annotion.CURDLog;
import cn.hzc.fortess.core.common.annotion.CURDType;
import cn.hzc.fortess.core.common.constant.Const;
import cn.hzc.fortess.core.common.exception.ServiceException;
import cn.hzc.fortess.core.shiro.ShiroKit;
import cn.hzc.fortess.system.common.EnableStatus;
import cn.hzc.fortess.system.dao.DeptDao;
import cn.hzc.fortess.system.entity.Dept;
import cn.hzc.fortess.system.entity.Lessee;
import cn.hzc.fortess.system.node.ZTreeNode;
import cn.hzc.fortess.system.page.Pagination;
import cn.hzc.fortess.system.search.DeptSearch;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    DeptDao deptDao;

    @Autowired
    UserService userService;

    @Override
    @CURDLog(value = "新增部门")
    public void add(Dept entity) {
        this.deptSetPids(entity);
        entity.setCreateTime(new Date());
        entity.setCreateUser(ShiroKit.getUser().getAccount());
        deptDao.insert(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CURDLog(value = "更新部门",curdType = CURDType.EDIT)
    public void update(Dept entity) {

        this.deptSetPids(entity);
        entity.setUpdateTime(new Date());
        entity.setUpdateUser(ShiroKit.getUser().getAccount());
        deptDao.update(entity);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CURDLog(value = "删除部门",curdType = CURDType.DELETE)
    public void delete(Integer id) {
        List<Dept> subDepts = deptDao.likePids(id);
        if (!CollectionUtils.isEmpty(subDepts)) {
            for (Dept dept : subDepts) {
                deptDao.delete(dept.getId());
                userService.deleteByDept(dept.getId());
            }
        }
        userService.deleteByDept(id);
        deptDao.delete(id);
    }

    @Override
    public Dept getById(Integer id) {
        return deptDao.findById(id);
    }

    @Override
    public Integer getRootDeptByLessee(Integer lesseeId) {
        return deptDao.findRootDeptByLessee(lesseeId);
    }

    @Override
    public Pagination getPage(DeptSearch search) {
        search.setLesseeId(ShiroKit.getUser().isAdministrator() ? null : ShiroKit.getUser().getLesseeId());
        Pagination pagination = new Pagination();
        pagination.setCount(deptDao.count(search));
        if (pagination.getCount() > 0) {
            pagination.setData(deptDao.page(search));
        }
        return pagination;
    }

    @Override
    public List<ZTreeNode> tree() {
        return deptDao.tree(ShiroKit.getUser().isAdministrator() ? null : ShiroKit.getUser().getLesseeId());
    }

    @Override
    @CURDLog(value = "创建根组织")
    public void createDeptRootByLessee(Lessee lessee) {
        Dept dept = new Dept();
        dept.setParentId(Const.TREE_ROOT_PARENT_ID);
        dept.setParentIds(Const.TREE_ROOT_PARENT_IDS);
        dept.setDeptName(lessee.getName());
        dept.setIdx(Const.DEFAULT_IDX);
        dept.setStatus(EnableStatus.ENABLE.getStatus());
        dept.setLesseeId(lessee.getId());
        dept.setMemo("自动创建的根组织");
        dept.setCreateTime(new Date());
        dept.setCreateUser(ShiroKit.getUser().getAccount());
        deptDao.insert(dept);
    }


    private void deptSetPids(Dept dept) {
        if (Const.isTreeRoot(dept.getParentId())) {
            dept.setParentId(Const.TREE_ROOT_PARENT_ID);
            dept.setParentIds(Const.TREE_ROOT_PARENT_IDS);
        } else {
            Integer pid = dept.getParentId();
            Dept temp = this.getById(pid);
            String pids = temp.getParentIds();
            dept.setParentId(pid);
            dept.setParentIds(pids + "[" + pid + "],");

            if(dept.getParentIds().split(",").length>Const.LEVEL_DEPT){
                throw new ServiceException(BizErrorEnum.CANT_OUT_LEVEL);
            }
        }
    }
}
